home *** CD-ROM | disk | FTP | other *** search
- XaAES - XaAES ain't AES
- ╜1995, Data Uncertain Software
- Written By Craig Graham.
- --
-
- PROGRAMMERS DOCUMENTATION
-
- This document is intended to give an overview of the underlying architecture
- of the XaAES GUI and details for XaAES specific programming.
-
- NOTE: I should really move over to using sockets to speed things up instead of
- using pipes, but I'll have to write an installer to setup MiNT-net first
- (a worthy project....)
-
- CONTENTS
-
- 1. INTRODUCTION
- 2. ARCHITECTURE OF XAAES
- x. WIDGET HANDLERS
-
- y. AES Extentions
-
- 1) Introduction
- ----------------
-
- After using MultiTOS, then AES4.1, I became frustrated at the lack of a decent
- GUI to use the real power of the MiNT kernal - X-Windows is all very
- well, but I cann't run GEM programs on it (and it's only black & white under
- MiNT). The W window system is ok but not widely used or available. The Mgr
- system (Bellcore Windows Manager) is seriously out of date (looks and feels
- rubbish), and again no GEM.
-
- MultiTOS (even AES4.1) is too slow. Geneva didn't run with MiNT (and, having
- tried the new MiNT compatible version, I can say it wasn't very compatible
- - at least AES4.1 is quite stable, if a little slow). MagiC lives in a very
- fast, very small world all it's own (no networking support, few programs
- written to exploit it).
-
- Firstly it is important to note that you can use & program XaAES without
- reading this - it provides a GEM compatible call interface via the
- standard GEM AES trap vector (trap 2).
-
- More advanced programs can be produced using XaAES's non-blocking call
- interface which allows programs to make multiple calls without blocking
- to wait for replies from the AES.
-
- Here's a few important general points about XaAES before we get technical:
-
- o It works only with MiNT - the architecture was designed to use MiNT,
- and so you must have it.
- o Being written especially for MiNT, it is a real MultiTasking GUI
- that can run GEM programs, not a slow & unwieldy kludge like MultiTOS.
- o Groovy sculpted 3D interface.
- o Colour icon support for all machines.
- o No busy waiting in the AES.
- o Client-Server architecture.
- o The source is freely available. Anyone can change the code, if they send
- patches to me with descriptions I'll included them into the next version.
- In fact the whole point of this document is to give people enough info
- to work on the code themselves.
- o Built with a 'real' C compiler (Lattice) not GNU
- (in spite of the denisons of comp.sys.atari.st.tech and the gem-list
- who wanted me to use GNU).
- o Extended fast interface for use by XaAES aware programs.
- Extended call interface allows XaAES aware applications to make AES calls
- without blocking to wait for replies they don't want, and to make multiple
- AES calls (calls to the AES server are queued).
- o Works with NVDI (NOTE: NVDI must be loaded before XaAES in order to work,
- otherwise strange things will happen).
-
- 2) Architecture Of XaAES
- -------------------------
- XaAES is really three distinct comoponents:
-
- o XaAES GUI server. This is deals with all the windows & stuff. It uses the
- existing VDI to produce it's graphics (and works fine with NVDI).
- Most of the time the server is blocked reading from it's command pipe
- - this means that unless it is actually doing something it doesn't use
- any CPU time at all. The server runs completely in user mode, and so
- can be pre-empted by MiNT at any time (unlike MultiTOS).
- o The GEM trap interface handler. This is actually part of the GUI server,
- but it is run under the process id of the client (so I don't allow it
- to access any of XaAES's data structures). It serves to serialise calls
- to the AES, and drop them into a command pipe to the sercer. It then blocks
- the client to wait for the AES server to service the command and reply.
- This bit is quite dodgy as it makes OS calls from inside a trap
- interupt, and I'm not altogether certain this was a legal thing to do.
- It works, so it stays....
- As of beta2, there has also been a direct call mechanism as well, which
- allows certain functions to be called directly by the client in the way
- normal GEM does, bypassing the command pipe altogether.
- o The 'moose.xdd' mouse device handler. This provides the mouse handling
- services required by XaAES via a new MiNT device /dev/moose. This is
- written in assembler (by James Cox), and although written especially
- for XaAES, it is an independent program which could be used by other
- applications as well as XaAES.
-
- The XaAES GUI server manages the window system, and commumicates with the rest
- of the system via MiNT pipes. In order to run standard GEM programs, it also
- replaces the standard AES trap handler with a small routine that fields trapped
- calls and drops them into a server command pipe on behalf of the application
- (this is done transparently, the application see's it as being the ordinary
- GEM AES trap). This is slightly slower than accessing the command pipe directly,
- but is totally compatible with GEM.
-
- 3) The XaAES Kernal
- ---------------------
-
- The XaAES kernal consists of a small assembler routine to catch the TRAP#2 vector,
- another small C routine in handler.c which provides the interface to the XaAES pipe
- based client/server AES for normal GEM applications.
-
- 3.1) The Command Pipe Interface
- ---------------------------------
-
- Most commands go via the clients private command pipe.
-
- The server must first be introduced to the client however, so there is a shared
- command pipe '/pipe/XaAES.cmd', where appl_init() will drop an XA_NEW_CLIENT message.
-
- The server then responds by creating a bi-directionial command/reply pipe for the
- application. The client then uses this to communicate with the AES server kernal.
- (NOTE: The server uses Fselect() on all the client command pipes.)
- When an AES trap occurs, the handler drops the pointer to the parameter block into
- it's command pipe.
-
- There are then 3 modes that the AES could have been called in.
-
- If standard GEM emulation mode (trap2 entered with d0=0xc8) the handler then drops
- back into user mode and blocks whilst reading on the current process's reply pipe.
- This allows other processes to execute whilst XaAES is performing AES functions
- (the XaAES server runs wholely in user mode so it's more MiNT-friendly than
- MultiTOS). The server writes back to the clients reply pipe with the reply when
- it has serviced the command - this unblocks the client which then returns from
- the exception.
-
- If NOREPLY mode is used, the AES doesn't block the calling process to wait
- for a reply - and indeed, won't generate one.
-
- If NOBLOCK mode is used, the AES doesn't block the calling process - but does
- place the result in the client's reply pipe. The client is then expected to
- handle it's own reply pipe. This allows multiple AES calls to be made without
- blocking a process, so an app could make all it's GEM initialisation calls
- at one go, then go on to do it's internal initialisation before coming back
- to see if the AES has serviced it's requests (less blocking in the client,
- and better multitasking).
- The result will be a short with the low byte being one of:
- XA_OK - The op-code was supported & was executed
- XA_UNIMPLEMENTED - You may have used a valid op-code, but XaAES doesn't
- yet support it.
- XA_ILLEGAL - The op-code was invalid in the first place, or there
- was some other problem with the parameters....
- XA_T_WAIT - Re-select for a evnt_timer format timeout
- XA_M_WAIT - Re-select for a evnt_multi format timeout
-
- For either XA_T_WAIT or XA_M_WAIT, the upper 3 bytes will contain a timeout
- value. This should be multiplied by 16 to get the timeout in milliseconds:
-
- So, you would make the call then get the response using this method:
- /* Do some GEM call here */
- Fread(reply_pipe_handle,sizeof(short),&response);
- timeout=response&0xfff0;
- response&=0xf;
- if ((response==XA_T_WAIT)||(response==XA_M_WAIT))
- {
- select_mask=1L<<reply_pipe_handle;
- timeout=Fselect(timeout,&select_mask,NULL,NULL);
- if (!timeout)
- /* Command timed out */
- else
- /* Command didn't time out */
- }
-
- You can use NOBLOCK mode in conjunction with evnt_multi() to do nifty tricks
- like using Fselect() to wait for AES events and serial data, or perhaps listen
- to a socket, all at the same time......
-
- NOTE: The reply pipe is opened on behalf of the client by appl_init(). The file handle
- can be found either by calling appl_pipe() from the XaAESLIB extention library, or
- from the application's global array at global[12].
-
- The main kernal handler is in kernal.c : void kernal(void);
-
- When an AES function packet is read from the command pipe, and the op-code is
- used to call an AES function handler routine via the Ktable[] array. A NULL
- in this array indicates an un-implemented function, otherwise it contains a
- pointer to an 'AESroutine' type function. These functions are always of type:
-
- short XA_objc_draw(short clnt_pid, AESPB *pb) { }
-
- The pb parameter (obviously) always points to the AES parameter block for the
- call, and clnt_pid is the MiNT process id of the client making the call.
- NOTE: In XaAES MiNTpid==AESid.
-
- Details of a client can be found in the XA_CLIENT clients[]; array
- (index on clnt_pid).
-
- The return value of a call is crucial - if the function returns TRUE (1) then
- the kernal will write to the clients reply pipe 'u:\pipe\XaClnt.<PID>' to unblock
- the process (in NOBLOCK or NOREPLY modes, the client won't have blocked anyway).
- If FALSE (0) is returned by the function, then the kernal leaves the client blocked
- - this is how functions like evnt_multi() block to wait for an event. The occurance
- of the event causes the value to be written to the reply pipe to unblock the client.
-
- x) Widget Handlers
- -------------------
- XaAES uses callback functions to handle all window widgets. These are refered
- to as 'behaviours'. Each widget has 4 behaviours - CLICK, DCLICK, DRAG &
- DISPLAY. These are held in an XA_WIDGET structure (see the file XA_TYPES.H).
- Each window has a set of these structures associated with it. The advantage
- of this is that the behaviour of a widget can be modified on a window by window
- basis (how it's displayed, what happens when it's clicked on, etc).
-
- CLICK - called whenever the user single clicks on the widget
- DCLICK - called when the user double clicks on the widget
- DRAG - called with the mouse button down when the user clicks and holds the
- button down on the widget
- DISPLAY- called to display the widget whenever the window is redrawn or the
- status of the widget changes. XaAES will set up appropriate clip
- rectangles before calling this behaviour, so all it has to do is draw
- the thing - taking into account the status of the widget (selected,
- etc).
-
- Not all widgets will need all the behaviours. For example, the standard GEM
- closer widget has only CLICK and DISPLAY behaviours, you cann't drag the closer
- and a double click does nothing, so they are left as NULL to signify that
- they aren't valid.
-
- GENERAL PRINCIPLE: If a widget isn't to behave in a certain way, set that
- behaviour to NULL.
-
- A widget handler is passed two parameters when it is called :
- XA_WINDOW *wind - the window which the widget is a part of
- XA_WIDGET *widg - the widget descriptor
-
- These contain all the info a widget needs.
-
- The handler itself should be of this type:
-
- short widget_handler_routine(XA_WINDOW *wind, XA_WIDGET *widg) { }
-
- The XA_WIDGET structure looks like this:
-
- typedef struct xa_widget {
- XA_WIDGET_LOCATION loc; // Location of widget relative to window extents
- WidgetCallback behaviour[COUNT_XACB]; // Callback function pointers to the behaviours of the widget
- XA_WIDGET_STATUS stat; // Current status (selected, etc)
- short w,h; // dimensions
- short click_x,click_y; // If we are displaying because we've been clicked on, this is the location
- // of the click (this is only used by the slider widget really)
- void *stuff; // Pointer to widget dependant context data, if any
- } XA_WIDGET;
-
- The behaviour[] array contains pointers to all the behaviours for the widget.
-
- w & h define the size of the widget - used to detect mouse events on the widget.
- When a mouse event occurs, the click_x & click_y values are filled in with the
- location of the click event prior to calling the widget handler.
-
- All widgets have relative locations like X-Windows widgets (attribute 'loc').
- This is useful, as you can specify a widget as (RB, 1, 1) and it will always be
- displayed starting with it's coords in the bottom-right of the window. Possible
- relative coords are:
-
- LT : top left
- CT : centred top (y relative to top, x recalculated to be window width / 2)
- RT : top right
- LB : bottom left
- CB : centred bottom
- RB : bottom right
-
- An example use of this is the SIZER widget, which always keeps the same location
- relative to the bottom-right of the window, even when the window moves & changes
- size.
- The utility routine
-
- void rp_2_ap(XA_WINDOW *wind, XA_WIDGET *widg, short *x, short *y);
-
- changes relative coords into absolute screen coordinates (returned in x & y).
-
- When displaying, a widget should check it's state attribute 'stat' (normally
- XAW_PLAIN). If this is set to XAW_SELECTED then the widget should display
- itself in some 'selected' form - anything will do, just invert it like
- old GEM, or do a 3D push like AES4, maybe do some little animations like
- my default widget set does.
-
- The final element of the XA_WIDGET structure is void *stuff; this is provided
- so certain widgets can have extra information kept with them - the scroll bars
- for instance keep a pointer to an XA_SLIDER_WIDGET structure here to maintain
- their size & position information.
-
- It is intended that a user program in the know will be able to change the
- default behaviours of it's own window widgets, so a desktop could change
- the CLICK behaviour of the close widget for directory windows to make the
- window go back up a level instead of sending a WM_CLOSED, and perhaps display
- as a << arrow instead of a closer box.
-
- User programs can also add their own custom widgets to a window, and they will
- behave in exactly the same way as the standard GEM widgets (the same behaviour
- based system).
-
- Widgets should be informative and 'nice', so the XaAES versions of the standard
- GEM widgets (CLOSE, RESIZE, etc) are implemented as colour bitmaps (designed
- using Interface - get it it's cool) with seperate 'selected' images. This allows
- the CLOSE widget to display as an ordinary looking button, but get a little red
- alert sign with a '!' in it when you click on it.
-
- y. AES EXTENSIONS
- -------------------
-
- XaAES provides several extensions to the standard AES that provide more features.
- This section details exactly what these features are. Where possible, I've tied
- up with the oAESis authors to get support for these features in two AES's.
-
- The file XAAESLIB.H provides bindings for the extended functions.
-
- y.1 appl_init()
- ----------------
- The file handle of the clients command/reply pipe is available in global[12].
-
- y.2 shel_write()
- -----------------
- We've extended shel_write() to support the concept of a multi-user system provided
- by MiNT.
-
- When a program uses shel_write to launch a child, the default behaviour
- (under XaAES) is that the 'AES child' inherits the user id & group id of the
- process that launched it.
-
- An extension to the AES4.0 shel_write() mode 0 is provided in the form of:
-
- #define SW_UID 0x1000 /* Set user id of launched child */
- #define SW_GID 0x2000 /* Set group id of launched child */
-
- typedef struct _xshelw {
- char *newcmd;
- LONG psetlimit;
- LONG prenice;
- char *defdir;
- char *env;
- short uid; /* New child's UID */
- short gid; /* New child's GID */
- } XSHELW;
-
- This is used in the same way as the AES4.0 SHELW structure and is compatible - using
- the extended structure won't kill AES4.0, the UID/GID fields will simply be ignored.
- The extra fields uid & gid allow you to explicitly set the child's user & group id.
-
- NOTE: This was agreed with the authors of Geneva and oAESis as well as XaAES....
-
-
-